import { VuexModule, Module, Action, getModule, Mutation } from 'vuex-module-decorators'
import { lpMine_CONTRACT, lpMineAbi } from '@/contract'
import { ethers } from "ethers";
import { toWei } from '@/utils/format'


import store from '@/store'

export interface lpMineState {
}

@Module({ dynamic: true, store, name: 'lpMine', namespaced: true })
class lpMine extends VuexModule implements lpMineState {

    @Action({ rawError: true })
    public isUserExists(address = store.getters.userAddr): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.isUserExists(address).call()
    }

    @Action({ rawError: true })
    public getPrice(): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.getPrice().call()
    }
    @Action({ rawError: true })
    public nodeNum(): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.nodeNum().call()
    }

    @Action({ rawError: true })
    public contractInfo(): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.contractInfo().call()
    }

    @Action({ rawError: true })
    public userInfo(address = store.getters.userAddr): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.userInfo(address).call()
    }

    @Action({ rawError: true })
    public getWithdrawableStatic(address = store.getters.userAddr): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.getWithdrawableStatic(address).call()
    }

    @Action({ rawError: true })
    public userReward(address = store.getters.userAddr): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.userReward(address).call()
    }

    @Action({ rawError: true })
    public getDirectsByPage({ pageNum, pageSize }: { pageNum: number, pageSize: number }): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.getDirectsByPage(store.getters.userAddr, pageNum, pageSize).call()
    }

    @Action({ rawError: true })
    public calU(amount: string | number): Promise<any> {
        const contract = new store.getters.web3.eth.Contract(lpMineAbi, lpMine_CONTRACT);
        return contract.methods.calU(toWei(amount)).call()
    }

    @Action({ rawError: true })
    public async stake(amount: string | number): Promise<any> {
        const ethersProvider = new ethers.providers.Web3Provider(
            window.ethereum,
            "any"
        );
        const contract = new ethers.Contract(
            lpMine_CONTRACT,
            lpMineAbi,
            ethersProvider.getSigner()
        );
        const result = await contract.stake(
            store.getters.referrer || store.getters.userAddr,
            toWei(amount),
            0
        );
        return result.wait()
    }

    @Action({ rawError: true })
    public async stakeSecond(amount: number | string): Promise<any> {
        const ethersProvider = new ethers.providers.Web3Provider(
            window.ethereum,
            "any"
        );
        const contract = new ethers.Contract(
            lpMine_CONTRACT,
            lpMineAbi,
            ethersProvider.getSigner()
        );
        const result = await contract.stakeSecond(toWei(amount));
        return result.wait()
    }

    @Action({ rawError: true })
    public async getReward(): Promise<any> {
        const ethersProvider = new ethers.providers.Web3Provider(
            window.ethereum,
            "any"
        );
        const contract = new ethers.Contract(
            lpMine_CONTRACT,
            lpMineAbi,
            ethersProvider.getSigner()
        );
        const result = await contract.getReward();
        return result.wait()
    }

    @Action({ rawError: true })
    public async getTeamReward(): Promise<any> {
        const ethersProvider = new ethers.providers.Web3Provider(
            window.ethereum,
            "any"
        );
        const contract = new ethers.Contract(
            lpMine_CONTRACT,
            lpMineAbi,
            ethersProvider.getSigner()
        );
        const result = await contract.getTeamReward();
        return result.wait()
    }

    @Action({ rawError: true })
    public async getNodeReward(): Promise<any> {
        const ethersProvider = new ethers.providers.Web3Provider(
            window.ethereum,
            "any"
        );
        const contract = new ethers.Contract(
            lpMine_CONTRACT,
            lpMineAbi,
            ethersProvider.getSigner()
        );
        const result = await contract.getNodeReward();
        return result.wait()
    }

}

export const lpMineModule = getModule(lpMine)